import { Destroyable, react, reactJson, Event, track, HasOwner, reactJsonWithUndefined } from "earthsdk3";
import { MyProjectManager } from "../MyProjectManager";
import { ObjResettingWithEvent } from "earthsdk3";
import { ESRtsFeatureEditing } from "earthsdk3";
import { getsceneObjNumfromSceneTree } from "../utils";
import { ElMessage } from "element-plus";
import { ESRtsEexturedPolygon } from "../esobjs/ESRtsEexturedPolygon";
import { ESRtsPolygon } from "../esobjs/ESRtsPolygon";
import { reqChangeDefinitionl } from "@/api";
import loading from "@/api/loading";

function isNumber(value: any): boolean {
    return typeof value === 'number' && !isNaN(value);
}

const selectmagfilter = [
    {
        type: 'NEAREST',
        value: 9728
    },
    {
        type: 'LINEAR',
        value: 9729
    },


]

const selectminfilter = [
    {
        type: 'NEAREST',
        value: 9728
    },
    {
        type: 'LINEAR',
        value: 9729
    },
    {
        type: 'NEAREST_MIPMAP_NEAREST',
        value: 9984
    },
    {
        type: 'LINEAR_MIPMAP_NEAREST',
        value: 9985
    },
    {
        type: 'NEAREST_MIPMAP_LINEAR',
        value: 9986
    },
    {
        type: 'LINEAR_MIPMAP_LINEAR',
        value: 9987
    }

]
let timer = null as any

class PickResettting extends Destroyable {
    constructor(featureEdit: FeatureEdit, owner: MyProjectManager) {
        super();
        const eSRtsTileset = owner.cimrtsManager.eSRtsTileset
        const viewer = owner.activeViewer

        if (!viewer) return;
        this.dispose(viewer.clickEvent.don(async e => {

            if (!e.screenPosition) return;
            // 拾取
            const obj = await eSRtsTileset.pickFeature(viewer, e.screenPosition)

            console.log(obj);

            // 选中的id
            const currentFeatureId = obj?.featureId

            // pick选中内置属性
            const pickInnerFields = obj?.pickInnerFields
            if (pickInnerFields) {
                for (const key in pickInnerFields) {
                    pickInnerFields[key] = typeof pickInnerFields[key] === 'bigint' ? pickInnerFields[key].toString() + 'n' : pickInnerFields[key]
                }
            }
            if (this.isDestroyed() || !currentFeatureId) return;


            // 设置内置属性
            featureEdit.innerFields = Object.entries(pickInnerFields).map((e: any) => {
                return {
                    key: e[0],
                    value: e[1]
                }
            })
            const property = await eSRtsTileset.getFeatureProperty(currentFeatureId) as any;
            const param = property.geometry.param

            eSRtsTileset.ids.forEach(id => {
                let o = owner.getSceneObjectById(id) as ESRtsFeatureEditing
                if (o) {
                    eSRtsTileset.removeHighlightDSFeature(o)
                }

            })

            let sceneObject: ESRtsFeatureEditing | ESRtsPolygon | ESRtsEexturedPolygon | undefined = undefined

            // scenetree上面不存在
            if (!(owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(currentFeatureId))) {
                if (!owner.getSceneObjectById(currentFeatureId)) {
                    sceneObject = owner.createSceneObject(ESRtsFeatureEditing, currentFeatureId) as ESRtsFeatureEditing
                    // @ts-ignore
                    await sceneObject.init(eSRtsTileset, currentFeatureId)
                    // 高亮
                    eSRtsTileset.highlightDSFeature(sceneObject)
                } else {
                    sceneObject = owner.getSceneObjectById(currentFeatureId) as ESRtsFeatureEditing
                    const initOffset = [...(JSON.parse(JSON.stringify(sceneObject.offset ?? [0, 0, 0])))]
                    eSRtsTileset.highlightDSFeature(sceneObject)
                    sceneObject.dispose(sceneObject.tilesetReady.disposableOnce(async () => {
                        // @ts-ignore
                        sceneObject.offset = [...initOffset]
                        // @ts-ignore
                        if (sceneObject.materialOptions && sceneObject.changeMaterial) {
                            // @ts-ignore
                            await owner.cimrtsManager.materailsManager?.setMaterail(sceneObject, sceneObject.materialOptions, sceneObject.changeMaterial.oldMaterialId)
                        }
                    }))
                }
            } else {
                sceneObject = owner.getSceneObjectById(currentFeatureId) as ESRtsFeatureEditing
                const initOffset = [...(JSON.parse(JSON.stringify(sceneObject.offset ?? [0, 0, 0])))]
                eSRtsTileset.highlightDSFeature(sceneObject)
                sceneObject.dispose(sceneObject.tilesetReady.disposableOnce(async () => {
                    // @ts-ignore
                    sceneObject.offset = [...initOffset]
                    // @ts-ignore
                    if (sceneObject.materialOptions && sceneObject.changeMaterial) {
                        // @ts-ignore
                        await owner.cimrtsManager.materailsManager?.setMaterail(sceneObject, sceneObject.materialOptions, sceneObject.changeMaterial.oldMaterialId)
                    }
                }))
            }
            if (featureEdit.pickHidden) {
                featureEdit.editEvent.emit(currentFeatureId, 'pickHidden')
            }
            this.dispose(() => {
                if (!(owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(currentFeatureId))) {
                    sceneObject && owner.destroySceneObject(sceneObject)
                }
            })
        }))
    }
}

export class FeatureEdit extends HasOwner<MyProjectManager> {

    // 开启拾取
    private _enablePick = this.dv(react<boolean>(false));
    get enablePick() { return this._enablePick.value; }
    get enablePickChanged() { return this._enablePick.changed; }
    set enablePick(value: boolean) { this._enablePick.value = value; }

    // 拾取后隐藏
    private _pickHidden = this.dv(react<boolean>(false));
    get pickHidden() { return this._pickHidden.value; }
    get pickHiddenChanged() { return this._pickHidden.changed; }
    set pickHidden(value: boolean) { this._pickHidden.value = value; }

    // 点击编辑事件
    private _editEvent = this.dv(new Event<[string, string]>());
    get editEvent() { return this._editEvent; }

    // 拾取处理
    private _pickResettting = this.dv(new ObjResettingWithEvent(this.enablePickChanged, () => {
        if (!this.enablePick) return undefined;
        return new PickResettting(this, this.owner);
    }))
    get pickResettting() { return this._pickResettting; }


    // 内置属性
    private _innerFields = this.dv(reactJson<any>([]));
    get innerFields() { return this._innerFields.value; }
    get innerFieldsChanged() { return this._innerFields.changed; }
    set innerFields(value: any) { this._innerFields.value = value; }

    async setBeautifyMaterails(sceneObject: any) {
        if (!Object.entries(sceneObject.beautifyMaterails).length) return;
        const { beautifyMaterails } = sceneObject
        const datasetName = sceneObject.datasetName;
        const material: any = {}
        beautifyMaterails.baseColorFactor.enable && (material.baseColorFactor = [...beautifyMaterails.baseColorFactor.value])
        beautifyMaterails.metallicFactor.enable && (material.metallicFactor = beautifyMaterails.metallicFactor.value)
        beautifyMaterails.roughnessFactor.enable && (material.roughnessFactor = beautifyMaterails.roughnessFactor.value)
        beautifyMaterails.doubleSided.enable && (material.doubleSided = beautifyMaterails.doubleSided.value)
        beautifyMaterails.ulint.enable && (material.unlit = beautifyMaterails.ulint.value)
        beautifyMaterails.alphaModel.enable && (material.alphaMode = beautifyMaterails.alphaModel.value)
        beautifyMaterails.magfilter.enable && (material.magfilter = selectmagfilter.find((item) => item.value == beautifyMaterails.magfilter.value)?.type)
        beautifyMaterails.minfilter.enable && (material.minfilter = selectminfilter.find((item) => item.value == beautifyMaterails.minfilter.value)?.type)

        if (beautifyMaterails.baseColorTexture.enable && beautifyMaterails.baseColorTexture.value) {
            material.baseColorTexture = {
                value: `${this.owner.cimrtsManager.cimrtsIp}/ds/featuretiles/${datasetName}/${beautifyMaterails.baseColorTexture.value}`,
                offset: beautifyMaterails.baseColorTexture.translate,
                scale: beautifyMaterails.baseColorTexture.scale,
                rotate: beautifyMaterails.baseColorTexture.rotate,
            }
        }
        if (beautifyMaterails.normalTexture.enable && beautifyMaterails.normalTexture.value) {
            material.normalTexture = {
                value: `${this.owner.cimrtsManager.cimrtsIp}/ds/featuretiles/${datasetName}/${beautifyMaterails.normalTexture.value}`,
                offset: beautifyMaterails.normalTexture.translate,
                scale: beautifyMaterails.normalTexture.scale,
                rotate: beautifyMaterails.normalTexture.rotate,
            }
        }
        console.log("material", material);
        const res = await sceneObject.setMaterial(material)
        if (res.type == "warn") {
            ElMessage({
                message: res.message,
                type: 'warning',
            })
        }

    }

    // 修改要素对应几何体的清晰度
    async changeDefinitionl(featureId: string, offset: number) {
        try {
            const param = {
                "tileServiceName": this._tileServiceName,
                "featureId": featureId,
                "offset": offset
            }
            const res = await reqChangeDefinitionl(param)
            // @ts-ignore
            if (res.status !== 'ok') {
                loading.closeLoading()
                return;
            }
            ElMessage.success('清晰度修改成功')
            loading.closeLoading()

        } catch (error) {
            loading.closeLoading()
            console.log(error)
        }
    }

    init() {
        this.enablePick = true
    }
    clear() {
        this.enablePick = false
        this.pickHidden = false
        this.innerFields = []
    }

    constructor(private _tileServiceName: string, owner: MyProjectManager) {
        super(owner);
        const eSRtsTileset = owner.cimrtsManager.eSRtsTileset

        this.dispose(this.editEvent.disposableOn(async (currentFeatureId: string, type: string) => {
            if (!currentFeatureId) return;

            const property = await eSRtsTileset.getFeatureProperty(currentFeatureId) as any;
            const param = property.geometry.param

            let sceneObject: ESRtsFeatureEditing | ESRtsPolygon | ESRtsEexturedPolygon | undefined = undefined

            // 绘制对象 
            if (param) {
                const json = JSON.parse(param)
                // scenetree上面不存在
                if (!(owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(json.id))) {
                    // 删除高亮对象
                    const obj = owner.getSceneObjectById(currentFeatureId) as ESRtsFeatureEditing
                    // @ts-ignore
                    owner.destroySceneObject(obj)
                    sceneObject = owner.createSceneObjectFromJson(json) as ESRtsFeatureEditing | ESRtsPolygon
                    //隐藏原来大的中的feature
                    eSRtsTileset.setFeatureVisable('id', [{ value: currentFeatureId, visable: false }]);
                    sceneObject.d(() => { eSRtsTileset.setFeatureVisable('id', [{ value: currentFeatureId, visable: true }]) });

                    sceneObject.uiShowprops = property.allFields.map((e: any) => {
                        return {
                            featureClassName: e.featureClassName,
                            fields: e.fields.map((f: any) => {
                                return {
                                    key: f.name,
                                    type: f.type,
                                    value: f.type != "Double" ? f.value : (isNumber(f.value) ? Number(f.value.toFixed(3)) : "")
                                }
                            })
                        }
                    })
                    sceneObject.datasetName = property.datasetName
                    sceneObject.featureId = currentFeatureId
                    // @ts-ignore
                    sceneObject.geometryId = property.geometry.id
                    // @ts-ignore
                    sceneObject.create = false

                    const treeItem = owner.createdTreeItem(owner.cimrtsSceneTreeWrapper)
                    treeItem.sceneObject = sceneObject;
                    treeItem.name = sceneObject.name
                    owner.cimrtsSceneTreeWrapper?.uiTree.clearAllSelectedItems()
                    treeItem.uiTreeObject.selected = true
                } else {
                    sceneObject = owner.getSceneObjectById(json.id) as ESRtsFeatureEditing

                }
                if (type == "pickHidden" && this.pickHidden) {
                    const treeItem = owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(json.id)
                    treeItem && (treeItem.show = false)
                } else {
                    owner.propSceneTree = {
                        createOrEdit: type,
                        propType: "waterMend",
                        sceneObject: sceneObject,
                    }
                }
            } else {
                sceneObject = owner.getSceneObjectById(currentFeatureId) as ESRtsFeatureEditing

                {
                    if (type == "edit" && !(owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(currentFeatureId))) {
                        let message: any
                        sceneObject.ad(sceneObject.editingChanged.don(() => {
                            if (sceneObject?.editing) {
                                message = ElMessage({
                                    message: '1. 双击鼠标左键或点击ESC键退出编辑2. 点击空格键进行平移、旋转编辑方式的切换',
                                    duration: 0,
                                    plain: true,
                                })
                            } else {
                                message && message.close()
                            }
                        }))
                        sceneObject.ad(() => message && message.close())
                    }
                }

                if (!(owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(currentFeatureId))) {
                    const treeItem = owner.createdTreeItem(owner.cimrtsSceneTreeWrapper)
                    treeItem.sceneObject = sceneObject;
                    // type == "edit" && (sceneObject.editing = true)
                    const name = this.innerFields.find((e: any) => e.key === "name")?.value
                    const newName = "编辑要素_" + (name ? name : (sceneObject.id ? sceneObject.id : ""))
                    const num = getsceneObjNumfromSceneTree(sceneObject.typeName, owner.cimrtsSceneTreeWrapper)
                    treeItem.name = `${newName}(${num})`
                    owner.cimrtsSceneTreeWrapper?.uiTree.clearAllSelectedItems()
                    treeItem.uiTreeObject.selected = true
                }

                if (type == "pickHidden" && this.pickHidden) {
                    const treeItem = owner.cimrtsSceneTreeWrapper?.getTreeItemFromSceneObjId(currentFeatureId)
                    treeItem && (treeItem.show = false)
                } else {
                    owner.propSceneTree = {
                        createOrEdit: type,
                        propType: "featureEdit",
                        sceneObject: sceneObject,
                    }
                }


                // timer && clearTimeout(timer)
                // timer = setTimeout(async () => {
                //     await this.setBeautifyMaterails(sceneObject)
                // }, 200)

            }
        }))
    }
}







